package com.gwtgeo.ui.client.mvp.newmap;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.customware.gwt.dispatch.client.DispatchAsync;
import net.customware.gwt.presenter.client.EventBus;

import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.HasValue;
import com.google.inject.Inject;
import com.gwtgeo.service.model.WMSLayerDef;
import com.gwtgeo.ui.client.gin.GwtgeoGinFactory;
import com.gwtgeo.ui.client.mvp.desktop.DesktopPresenter;
import com.gwtgeo.ui.client.mvp.map.MapPresenter;
import com.gwtgeo.ui.client.mvp.windowsmanager.WindowTypeEnum;
import com.gwtgeo.ui.client.mvp.windowsmanager.WindowedDisplay;
import com.gwtgeo.ui.client.mvp.windowsmanager.WindowedPresenter;
import com.gwtgeo.ui.client.mvp.windowsmanager.WindowsParams;
import com.gwtgeo.ui.shared.event.CloseWinModalEvent;
import com.gwtgeo.ui.shared.rpc.GetBaseLayers;
import com.gwtgeo.ui.shared.rpc.GetBaseLayersResult;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.events.HasClickHandlers;
import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
import com.smartgwt.client.widgets.form.fields.events.HasChangedHandlers;

public class NewMapPresenter extends WindowedPresenter<NewMapPresenter.Display> {

	public interface Display extends WindowedDisplay {
		HasClickHandlers getAcceptClick();

		HasClickHandlers getCancelClick();

		HasText getName();

		HasText getProjection();

		HasText getBaseLayer();

		HasChangedHandlers getProjectionChange();

		HasValue<Float> getLongitude();

		HasValue<Float> getLatitude();

		void setBaseLayers(List<WMSLayerDef> layers);

		boolean validate();
	}

	private final DispatchAsync dispatcher;

	private List<WMSLayerDef> baseLayers;

	@Inject
	public NewMapPresenter(Display display, EventBus eventBus,
			MapPresenter mapPresenter, DispatchAsync dispatcher) {
		super(display, eventBus);
		this.dispatcher = dispatcher;
	}

	@Override
	public void init(Map<String, Object> params) {
	}

	@Override
	public WindowTypeEnum getType() {
		return WindowTypeEnum.NEW;
	}

	@Override
	protected void onBind() {
		super.onBind();
		this.registerHandler(display.getAcceptClick().addClickHandler(
				new ClickHandler() {

					@Override
					public void onClick(ClickEvent event) {
						if (display.validate()) {
							Map<String, Object> data = new HashMap<String, Object>();
							data.put(WindowsParams.MAP_NAME, display.getName()
									.getText());
							data.put(WindowsParams.MAP_PROJECTION, display
									.getProjection().getText());
							data.put(WindowsParams.MAP_CENTER_LATITUDE, display
									.getLatitude().getValue());
							data.put(WindowsParams.MAP_CENTER_LONGITUDE,
									display.getLongitude().getValue());
							data.put(WindowsParams.MAP_BASE_LAYER, getSelectedBaseLayer());
							eventBus.fireEvent(new CloseWinModalEvent(
									getType(), WindowTypeEnum.MAP, data));
							DesktopPresenter desktop = GwtgeoGinFactory.injector
									.getDesktopPresenter();
							// TODO PMA20100502 Think.
							desktop.retrieveWinData(getType(), data);
						}
					}
				}));

		this.registerHandler(this.display.getCancelClick().addClickHandler(
				new ClickHandler() {

					@Override
					public void onClick(ClickEvent event) {
						eventBus.fireEvent(new CloseWinModalEvent(getType()));
					}
				}));
		this.registerHandler(this.display.getProjectionChange()
				.addChangedHandler(new ChangedHandler() {

					@Override
					public void onChanged(ChangedEvent event) {
						dispatcher.execute(new GetBaseLayers(),
								new AsyncCallback<GetBaseLayersResult>() {

									@Override
									public void onFailure(Throwable arg0) {
										// TODO PMA20100509 Handle.
									}

									@Override
									public void onSuccess(
											GetBaseLayersResult result) {
										baseLayers = result.getLayers();
										display.setBaseLayers(baseLayers);
									}
								});

					}
				}));
	}

	@Override
	protected void onRevealDisplay() {
	}

	@Override
	protected void onUnbind() {
	}
	
	private WMSLayerDef getSelectedBaseLayer(){
		String name = display.getBaseLayer().getText();
		for(WMSLayerDef layer: baseLayers){
			if(name.equals(layer.getName())){
				return layer;
			}
		}
		return null;
	}
}